package org.genew.squadra.xml.model.builder;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import java.io.File;
import java.io.IOException;

import org.genew.squadra.xml.common.StatisticUtility;
import org.genew.squadra.xml.model.content.Content;
import org.genew.squadra.xml.model.epubbiblio.*;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import com.sun.org.apache.xpath.internal.NodeSet;

public class BiblioBuilder implements Builder {

	public static void buildBiblio(EpubBiblio biblio, XMLStreamWriter xmlv)
			throws XMLStreamException {
		xmlv.writeStartDocument("UTF-8", "1.0");
		xmlv.writeStartElement("ePubBiblio");
		xmlv.writeAttribute("xmlns", "http://org.genew.squadra.xml/epub");
		xmlv.writeAttribute("xmlns:xsi",
				"http://www.w3.org/2001/XMLSchema-instance");
		xmlv.writeAttribute("xsi:schemaLocation",
				"/ProvaSpringXML/src/org/genew/squadra/xml/model/builder ePubBiblio.xsd");
		xmlv.writeAttribute("numeroAutore",
				Integer.toString(biblio.getNumeroAutori()));
		xmlv.writeAttribute("numeroEditore",
				Integer.toString(biblio.getNumeroEdtori()));
		xmlv.writeAttribute("mfAutore", biblio.getAutorePiuPresente());
		xmlv.writeAttribute("mfEditore", biblio.getEditorePiuPresente());
		xmlv.writeAttribute("mediaImmagini",
				Integer.toString(biblio.getMediaImmagini()));
		xmlv.writeAttribute("totaleParole",
				Integer.toString(biblio.getTotaleParole()));
		xmlv.writeAttribute("totaleImmagini",
				Integer.toString(biblio.getTotaleImmagini()));
		xmlv.writeAttribute("totaleCapitoli",
				Integer.toString(biblio.getTotaleCapitoli()));
		Iterator i = biblio.getePubs().iterator();
		xmlv.writeStartElement("epubList");
		while (i.hasNext()) {
			Epub temp = (Epub) i.next();
			buildEpub(temp, xmlv);

		}
		xmlv.writeEndElement();
		i = biblio.getePubs().iterator();

		buildStat(biblio.getePubs(), xmlv);

		xmlv.writeEndElement();
		xmlv.writeEndDocument();
	}

	public static void buildEpub(Epub epub, XMLStreamWriter xmlv)
			throws XMLStreamException {

		xmlv.writeStartElement("ePub");
		Calendar cal = Calendar.getInstance();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); // yyyy-MM-dd'T'HH:mm:ss
		String dataxml = sdf.format(cal.getTime());
		xmlv.writeAttribute("id", Integer.toString(epub.getId()));
		xmlv.writeAttribute("dataInserimento", dataxml);
		xmlv.writeStartElement("titolo");
		xmlv.writeCharacters(epub.getTitolo());
		xmlv.writeEndElement();

		// xmlv.writeStartElement("id");
		// xmlv.writeCharacters(Integer.toString(epub.getId())); //AGGIUNTA
		// MATTEO
		// xmlv.writeEndElement();

		xmlv.writeStartElement("lingua");
		xmlv.writeCharacters(epub.getLingua());
		xmlv.writeEndElement();

		xmlv.writeStartElement("isbn");
		xmlv.writeCharacters(epub.getIsbn());
		xmlv.writeEndElement();

		if (epub.getAutore() != null) {
			xmlv.writeStartElement("autore");
			xmlv.writeCharacters(epub.getAutore());
			xmlv.writeEndElement();
		}
		if (epub.getEditore() != null) {
			xmlv.writeStartElement("editore");
			xmlv.writeCharacters(epub.getEditore());
			xmlv.writeEndElement();
		}
		if (epub.getFormato() != null) {
			xmlv.writeStartElement("formato");
			xmlv.writeCharacters(epub.getFormato());
			xmlv.writeEndElement();
		}
		if (epub.getOrigine() != null) {
			xmlv.writeStartElement("origine");
			xmlv.writeCharacters(epub.getOrigine());
			xmlv.writeEndElement();
		}
		if (epub.getTipo() != null) {
			xmlv.writeStartElement("tipo");
			xmlv.writeCharacters(epub.getTipo());
			xmlv.writeEndElement();
		}
		if (epub.getData() != null) {
			xmlv.writeStartElement("data");
			xmlv.writeCharacters(epub.getData());
			xmlv.writeEndElement();
		}
		if (epub.getCollaboratore() != null) {
			xmlv.writeStartElement("collaboratore");
			xmlv.writeCharacters(epub.getCollaboratore());
			xmlv.writeEndElement();
		}
		if (epub.getRelazione() != null) {
			xmlv.writeStartElement("relazione");
			xmlv.writeCharacters(epub.getRelazione());
			xmlv.writeEndElement();
		}
		if (epub.getDirittiAutore() != null) {
			xmlv.writeStartElement("dirittiautore");
			xmlv.writeCharacters(epub.getDirittiAutore());
			xmlv.writeEndElement();
		}
		if (epub.getDestinazione() != null) {
			xmlv.writeStartElement("destinazione");
			xmlv.writeCharacters(epub.getDestinazione());
			xmlv.writeEndElement();
		}
		if (epub.getDescrizione() != null) {
			xmlv.writeStartElement("descrizione");
			xmlv.writeCharacters(epub.getDescrizione());
			xmlv.writeEndElement();
		}
		if (epub.getSoggetto() != null) {
			xmlv.writeStartElement("soggetto");
			xmlv.writeCharacters(epub.getSoggetto());
			xmlv.writeEndElement();
		}
		if (epub.getImmagini() > 0) {
			xmlv.writeStartElement("immagini");
			xmlv.writeCharacters(Integer.toString(epub.getImmagini()));
			xmlv.writeEndElement();
		}

		xmlv.writeStartElement("parole");
		xmlv.writeCharacters(Integer.toString(epub.getParole()));
		xmlv.writeEndElement();

		xmlv.writeStartElement("capitoli");
		xmlv.writeCharacters(Integer.toString(epub.getCapitoli()));
		xmlv.writeEndElement();

		xmlv.writeStartElement("percorsofile");
		xmlv.writeCharacters(epub.getPathFile());
		xmlv.writeEndElement();

		xmlv.writeEndElement();

	}

	public static void buildStat(List<Epub> epub, XMLStreamWriter xmlv)
			throws XMLStreamException {

		xmlv.writeStartElement("stats");
		Map<String, Map<String, Integer>> liste = ListaStat
				.generaListaStat(epub);
		Map<String, Integer> autori = liste.get("autori");
		if (autori != null) {
			xmlv.writeStartElement("stat-autori");
			Iterator it = autori.entrySet().iterator();
			while (it.hasNext()) {
				Map.Entry pairs = (Map.Entry) it.next();
				System.out.println(pairs.getKey() + " = " + pairs.getValue());
				xmlv.writeStartElement("author");
				xmlv.writeStartElement("nome");
				xmlv.writeCharacters((String) pairs.getKey());
				xmlv.writeEndElement();
				xmlv.writeStartElement("frequenza");
				Integer j = (Integer) pairs.getValue();
				xmlv.writeCharacters(j.toString());
				xmlv.writeEndElement();
				xmlv.writeEndElement();
				it.remove(); // avoids a ConcurrentModificationException
			}
			xmlv.writeEndElement();

		}

		Map<String, Integer> editori = liste.get("editori");
		if (editori != null) {
			xmlv.writeStartElement("stat-editori");
			Iterator it = editori.entrySet().iterator();
			while (it.hasNext()) {
				Map.Entry pairs = (Map.Entry) it.next();
				System.out.println(pairs.getKey() + " = " + pairs.getValue());
				xmlv.writeStartElement("editor");
				xmlv.writeStartElement("nome");
				xmlv.writeCharacters((String) pairs.getKey());
				xmlv.writeEndElement();
				xmlv.writeStartElement("frequenza");
				Integer i = (Integer) pairs.getValue();
				xmlv.writeCharacters(i.toString());
				xmlv.writeEndElement();
				xmlv.writeEndElement();
				it.remove(); // avoids a ConcurrentModificationException
			}
			xmlv.writeEndElement();

		}
		xmlv.writeEndElement();
	}

	// if
	// xmlv.writeStartElement("ePub");
	// Calendar cal = Calendar.getInstance();
	// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
	// //yyyy-MM-dd'T'HH:mm:ss
	// String dataxml = sdf.format(cal.getTime());
	// xmlv.writeAttribute("dataInserimento", dataxml);
	// xmlv.writeStartElement("titolo");
	// xmlv.writeCharacters(epub.getTitolo());
	// xmlv.writeEndElement();

	public static void updateBiblio(String pathFile, List<Epub> epub) {
		String filePath = pathFile;
		File epubBiblio = new File(filePath);
		DocumentBuilderFactory f = DocumentBuilderFactory.newInstance();
		DocumentBuilder dBuilder;
		try {
			dBuilder = f.newDocumentBuilder();
			Document doc = dBuilder.parse(epubBiblio);
			doc.getDocumentElement().normalize();

			addEpubElement(doc, epub);
			updateStatsElement(doc, epub);

			doc.getDocumentElement().normalize();
			TransformerFactory transformerFactory = TransformerFactory
					.newInstance();
			Transformer transformer = transformerFactory.newTransformer();
			DOMSource source = new DOMSource(doc);
			StreamResult result = new StreamResult(new File(filePath));
			transformer.setOutputProperty(OutputKeys.INDENT, "yes");
			transformer.transform(source, result);
			System.out.println("XML file updated successfully");

		} catch (SAXException | ParserConfigurationException | IOException
				| TransformerException e1) {
			e1.printStackTrace();
		}

	}

	private static void addEpubElement(Document doc, List<Epub> epub) {

		String realPath = doc.getDocumentURI();
		String a = realPath.replace("file:/", "");
		
		String b = a.replace("/", File.separator);
		int id = StatisticUtility.getIdStart(b);
		for (Iterator iterator = epub.iterator(); iterator.hasNext();) {
			Epub epub2 = (Epub) iterator.next();
			Element radice = doc.createElement("ePub");
			Calendar cal = Calendar.getInstance();
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); // yyyy-MM-dd'T'HH:mm:ss
			String dataxml = sdf.format(cal.getTime());
			radice.setAttribute("dataInserimento", dataxml);// //attributo
				
				
//				Element parent = (Element) doc.getElementsByTagName("epubList");
//				Element parentAtt = (Element) parent.getLastChild().getAttributes();
//				int id = Integer.parseInt(parentAtt.getAttribute("id"));
				
				radice.setAttribute("id", Integer.toString(id));
				id ++;
				
			if (epub2.getTitolo() != null) {
				Element titolo = doc.createElement("titolo");
				titolo.setTextContent(epub2.getTitolo());
				radice.appendChild(titolo);
			}

			if (epub2.getLingua() != null) {
				Element lingua = doc.createElement("lingua");
				lingua.setTextContent(epub2.getLingua());
				radice.appendChild(lingua);
			}
			if (epub2.getIsbn() != null) {
				Element isbn = doc.createElement("isbn");
				isbn.setTextContent(epub2.getIsbn());
				radice.appendChild(isbn);
			}
			if (epub2.getAutore() != null) {
				Element autore = doc.createElement("autore");
				autore.setTextContent(epub2.getAutore());
				radice.appendChild(autore);
			}
			if (epub2.getEditore() != null) {
				Element editore = doc.createElement("editore");
				editore.setTextContent(epub2.getEditore());
				radice.appendChild(editore);
			}
			if (epub2.getFormato() != null) {
				Element formato = doc.createElement("formato");
				formato.setTextContent(epub2.getFormato());
				radice.appendChild(formato);
			}
			if (epub2.getOrigine() != null) {
				Element origine = doc.createElement("origine");
				origine.setTextContent(epub2.getOrigine());
				radice.appendChild(origine);
			}
			if (epub2.getTipo() != null) {
				Element tipo = doc.createElement("tipo");
				tipo.setTextContent(epub2.getTipo());
				radice.appendChild(tipo);
			}
			if (epub2.getData() != null) {
				Element data = doc.createElement("data");
				data.setTextContent(epub2.getData());
				radice.appendChild(data);
			}
			if (epub2.getCollaboratore() != null) {
				Element collaboratore = doc.createElement("collaboratore");
				collaboratore.setTextContent(epub2.getCollaboratore());
				radice.appendChild(collaboratore);
			}
			if (epub2.getRelazione() != null) {
				Element relazione = doc.createElement("relazione");
				relazione.setTextContent(epub2.getRelazione());
				radice.appendChild(relazione);
			}
			if (epub2.getDirittiAutore() != null) {
				Element da = doc.createElement("dirittiautore");
				da.setTextContent(epub2.getDirittiAutore());
				radice.appendChild(da);
			}
			if (epub2.getDestinazione() != null) {
				Element destinazione = doc.createElement("destinazione");
				destinazione.setTextContent(epub2.getDestinazione());
				radice.appendChild(destinazione);
			}
			if (epub2.getDescrizione() != null) {
				Element descrizione = doc.createElement("descrizione");
				descrizione.setTextContent(epub2.getDescrizione());
				radice.appendChild(descrizione);
			}
			if (epub2.getSoggetto() != null) {
				Element soggetto = doc.createElement("soggetto");
				soggetto.setTextContent(epub2.getSoggetto());
				radice.appendChild(soggetto);
			}

			if (epub2.getImmagini() > 0) {
				Element immagini = doc.createElement("immagini");
				immagini.setTextContent(Integer.toString(epub2.getImmagini()));
				radice.appendChild(immagini);
			}

			Element parole = doc.createElement("parole");
			parole.setTextContent(Integer.toString(epub2.getParole()));
			radice.appendChild(parole);

			Element capitoli = doc.createElement("capitoli");
			capitoli.setTextContent(Integer.toString(epub2.getCapitoli()));
			radice.appendChild(capitoli);

			Element percorso = doc.createElement("percorsofile");
			percorso.setTextContent(epub2.getPathFile());
			radice.appendChild(percorso);

			Node giustaPosizione = doc.getElementsByTagName("epubList").item(0);

			giustaPosizione.appendChild(radice);
		}

	}

	private static void updateStatsElement(Document doc, List<Epub> epub) {

		for (Iterator iterator = epub.iterator(); iterator.hasNext();) {
			Epub epub2 = (Epub) iterator.next();
			String expression = "//stats/stat-autori/author[nome=\""+ epub2.getAutore()+"\"]";
			XPathFactory factory = XPathFactory.newInstance();
			XPath xPath = factory.newXPath();
			NodeList XMeta;
			try {
				XPathExpression espressione = xPath.compile(expression);
				XMeta = (NodeList) espressione.evaluate(doc, XPathConstants.NODESET);
				NodeList temp = doc.getElementsByTagName("author");
				
				
				if (XMeta.getLength()!=0) {
				
					Element autore = (Element) XMeta.item(0);
					
					String freqAutore = autore.getElementsByTagName("frequenza").item(0).getTextContent();
					String nomeAutore = autore.getElementsByTagName("nome").item(0).getTextContent();

					System.out.println("=====primo da incremenatre======="
							+ nomeAutore + freqAutore);
					boolean trovato = false;
					for (int i = 0; i < temp.getLength() - 1 || !trovato; i++) {

						Element author =  (Element) temp.item(i);
						if (author.getElementsByTagName("nome").item(0).getTextContent().equals(nomeAutore)) {
							if (!author.getElementsByTagName("frequenza").item(0).getTextContent()
									.equals(null)) {
								int x = Integer.parseInt(author.getElementsByTagName("frequenza").item(0).getTextContent());
								x++;
								author.getElementsByTagName("frequenza").item(0).setTextContent(Integer.toString(x));
								trovato = true;
							}
						}
					}
				}

				else {
					Element nuovoAutore = doc.createElement("author");
					Element nome = doc.createElement("nome");
					nome.setTextContent(epub2.getAutore());
					nuovoAutore.appendChild(nome);
					Element frequenza = doc.createElement("frequenza");
					frequenza.setTextContent(Integer.toString(1));
					nuovoAutore.appendChild(frequenza);
					temp.item(0).getParentNode().appendChild(nuovoAutore);
				}
				String expression2 = "//stats/stat-editori/editor[nome=\""
						+ epub2.getEditore() + "\"]";
				NodeList XMeta2;
				XMeta2 = (NodeList) xPath.compile(expression2).evaluate(doc,
						XPathConstants.NODESET);
				NodeList temp2 = doc.getElementsByTagName("editor");

				if (XMeta2.getLength() != 0) {

					Element editore = (Element) XMeta2.item(0);
					String nomeEditore = editore.getElementsByTagName("nome").item(0).getTextContent();
					String freqEditore = editore.getElementsByTagName("frequenza").item(0).getTextContent();
					System.out.println("=====primo da incremenatre======="
							+ nomeEditore + freqEditore);
					boolean trovato = false;
					for (int i = 0; i < temp2.getLength() - 1 || !trovato; i++) {
						Element editor = (Element) temp2.item(i);
						if (editor.getElementsByTagName("nome").item(0).getTextContent()
								.equals(nomeEditore)) {
							if (!editor.getElementsByTagName("frequenza").item(0).getTextContent()
									.equals(null)) {
							int x = Integer.parseInt(editor.getElementsByTagName("frequenza").item(0).getTextContent());
							x++;
							editor.getElementsByTagName("frequenza").item(0).setTextContent(
									Integer.toString(x));
							trovato = true;
							}
						}
					}
				} else {
					Element nuovoEditore = doc.createElement("editor");
					Element nome = doc.createElement("nome");
					nome.setTextContent(epub2.getEditore());
					nuovoEditore.appendChild(nome);
					Element frequenza = doc.createElement("frequenza");
					frequenza.setTextContent(Integer.toString(1));
					nuovoEditore.appendChild(frequenza);
					temp2.item(0).getParentNode().appendChild(nuovoEditore);
				}

			}

			catch (XPathExpressionException e) {
				// TODO Auto-generated catch block

				e.printStackTrace();

			}
		}
		
	}

}



